package com.lzs.adx.web.modules.adx.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lzs.adx.commmon.page.PageData;
import com.lzs.adx.commmon.service.impl.CrudServiceImpl;
import com.lzs.adx.commmon.utils.DateUtils;
import com.lzs.adx.web.modules.adx.dao.AccountReportDayDao;
import com.lzs.adx.web.modules.adx.dto.*;
import com.lzs.adx.web.modules.adx.entity.AccountReportDayEntity;
import com.lzs.adx.web.modules.adx.service.AccountReportDayService;
import com.lzs.adx.web.modules.adx.service.AccountService;
import com.lzs.adx.web.modules.adx.service.ReportTotalService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 账户日结算表
 *
 * @author wangzhijun 825400558@qq.com
 * @since 1.0.0 2024-09-02
 */
@Service
@Slf4j
public class AccountReportDayServiceImpl extends CrudServiceImpl<AccountReportDayDao, AccountReportDayEntity, AccountReportDayDTO> implements AccountReportDayService {

    @Autowired
    private AccountService accountService;

    @Autowired
    private ReportTotalService reportTotalService;

    @Override
    public QueryWrapper<AccountReportDayEntity> getWrapper(Map<String, Object> params){
        String id = (String)params.get("id");

        QueryWrapper<AccountReportDayEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(id), "id", id);

        return wrapper;
    }


    @Override
   public void generateData(ReportExcelDTO reportExcelDTO) {
        //非API
        if(reportExcelDTO.getType().equals(ReportExcelDTO.Tongtou)){
            AccountReportDayEntity accountReportDay=new AccountReportDayEntity();
            BeanUtils.copyProperties(reportExcelDTO,accountReportDay);
            accountReportDay.setMonth(DateUtils.getMonth(reportExcelDTO.getDay()));
            baseDao.insert(accountReportDay);
        }else{
            //API的方式
            handerApiData(reportExcelDTO);
        }
   }

    /**
     * API的方式数据处理
     * @param reportExcelDTO
     */
    private void handerApiData(ReportExcelDTO reportExcelDTO) {
        ReportTotalDTO reportTotalDTO=reportTotalService.getDetail(reportExcelDTO.getDspId(),reportExcelDTO.getDay());
        if(Objects.isNull(reportTotalDTO)){
            //无数据 跳过
            log.info("账号ID{}.账号名{} ,跳过");
            return;
        }

        //获取
        AccountDTO accountDTO = accountService.getDetail(reportTotalDTO.getDspId());
        //转换类型
        String keyType = accountDTO.getKeyType();
        //获取转化指标的值
        Long keyValue = getKeyValue(reportTotalDTO, keyType);
        //如果外部传入了转换总数，以外部为准，外部没有填写，则用转化总数
        Long actValue = Objects.nonNull(reportExcelDTO.getActEventTypeTotal())&&reportExcelDTO.getActEventTypeTotal()>0?reportExcelDTO.getActEventTypeTotal():keyValue;

        //生成报表
        LambdaQueryWrapper<AccountReportDayEntity> lambdaQueryWrapper=new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(AccountReportDayEntity::getDay,reportTotalDTO.getDate());
        lambdaQueryWrapper.eq(AccountReportDayEntity::getDspId,reportTotalDTO.getDspId());
        lambdaQueryWrapper.eq(AccountReportDayEntity::getEventType,keyType);
        List<AccountReportDayEntity> accountReportDayEntities = baseDao.selectList(lambdaQueryWrapper);
        if(CollectionUtil.isNotEmpty(accountReportDayEntities)){
            AccountReportDayEntity dbAccountReportDay = accountReportDayEntities.get(0);
            AccountReportDayEntity newValue = new AccountReportDayEntity();
            BeanUtils.copyProperties(reportExcelDTO,newValue);
            newValue.setMonth(DateUtils.getMonth(reportExcelDTO.getDay()));
            newValue.setUpdateTime(new Date());
            newValue.setId(dbAccountReportDay.getId());
            baseDao.updateById(newValue);
        }else{
            AccountReportDayEntity newValue = new AccountReportDayEntity();
            BeanUtils.copyProperties(reportExcelDTO,newValue);
            newValue.setMonth(DateUtils.getMonth(reportExcelDTO.getDay()));
            newValue.setCreateTime(new Date());
            newValue.setUpdateTime(new Date());
            newValue.setEventType(keyType);
            newValue.setEventTypeTotal(keyValue);
            baseDao.insert(newValue);
        }
    }

    @Override
        public PageData<AccountReportDayDTO> findPage(Map<String, Object> params) {
            IPage<AccountReportDayDTO> listPage = baseDao.selectListPage(getPage(params, null, false), params);

            return new PageData<>(listPage.getRecords(), listPage.getTotal());
        }

        @Override
        public AccountReportDayDTO getDetail(String dspId, String day) {
            LambdaQueryWrapper<AccountReportDayEntity> lambdaQueryWrapper=new LambdaQueryWrapper();
            lambdaQueryWrapper.eq(AccountReportDayEntity::getDspId,dspId);
            lambdaQueryWrapper.eq(AccountReportDayEntity::getDay,day);
            AccountReportDayDTO accountReportDayDTO=new AccountReportDayDTO();
            AccountReportDayEntity accountReportDay = this.baseDao.selectOne(lambdaQueryWrapper);
            if(Objects.isNull(accountReportDay)){
                return null;
            }
            BeanUtils.copyProperties(accountReportDay,accountReportDayDTO);
            return accountReportDayDTO;
        }


        private static Long getKeyValue(ReportTotalDTO reportTotalDTO, String keyType)  {
            Long result=0l;
            try {
                Class<? extends ReportTotalDTO> aClass = reportTotalDTO.getClass();
                Method method = aClass.getMethod("get"+ StringUtils.capitalize(keyType));
                method.setAccessible(true);
                Object invoke = method.invoke(reportTotalDTO, null);
                if(Objects.isNull(invoke)){
                    return 0L;
                }
                return (Long) invoke;
            }catch (Exception e){
                log.error("h获取数据出现了移除，移除的错误为",e);
            }
            return result;
        }


    @Override
    public List<AccountReportMonthDTO> selectMonthReportData() {
        return baseDao.selectMonthReportData();
    }

    @Override
    public List<AccountReportMonthDTO> selectMonthLoanData() {
        return baseDao.selectMonthLoanData();
    }

    @Override
    public PageData<AccountReportDayDTO> findDayTotalPage(Map<String, Object> params) {
        IPage<AccountReportDayDTO> listPage = baseDao.selectDayTotalPage(getPage(params, null, false), params);

        return new PageData<>(listPage.getRecords(), listPage.getTotal());
    }
}